package userlogic

import (
	"context"
	"fmt"

	ar "gitee.com/liuxuezhan/ar-platform/jwttoken"
	"gitee.com/liuxuezhan/ar-platform/login-rpc/login_rpc"

	"gitee.com/liuxuezhan/ar-platform/login-rpc/internal/dao/model"
	"gitee.com/liuxuezhan/ar-platform/login-rpc/internal/svc"
	config "gitee.com/liuxuezhan/ar-platform/login-rpc/pkg/code"
	re "gitee.com/liuxuezhan/ar-platform/login-rpc/pkg/redis_utils"
	"github.com/zeromicro/go-zero/core/logx"
)

type ParseTokenLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewParseTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ParseTokenLogic {
	return &ParseTokenLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *ParseTokenLogic) ParseToken(in *login_rpc.ParseTokenRequest) (*login_rpc.ParseTokenResponse, error) {
	var err error
	var commonResp login_rpc.CommonResp
	if in.Token == "" {
		commonResp.Code = config.TokenError
		commonResp.Message = "empty token"
		return &login_rpc.ParseTokenResponse{CommonResp: &commonResp}, fmt.Errorf("empty token")
	}
	claims, err := ar.ParseRefreshToken(in.Token)
	if err != nil || claims.ID == 0 {
		commonResp.Code = config.TokenvalidateError
		commonResp.Message = "token has expired"
		return &login_rpc.ParseTokenResponse{CommonResp: &commonResp}, fmt.Errorf("token has expired")
	}

	// 先在redis中查询，没查询到再再数据库中匹配token是否被更新
	sign := re.GetTokenRedis(l.ctx, l.svcCtx.Config.RedisConfig, claims.ID, claims.IsAdmin, claims.Business, claims.Source)
	if sign == "" {
		if claims.IsAdmin {
			sign, _ = model.NewAdminLoginToken(l.ctx, l.svcCtx.Db).GetAdminSignByUserIdAndPlatform(claims.ID, claims.Source, claims.Business)
			if sign == "" || sign != claims.Sign {
				commonResp.Code = config.TokenvalidateError
				commonResp.Message = "token has expired"
				return &login_rpc.ParseTokenResponse{CommonResp: &commonResp}, fmt.Errorf("token has expired")
			}
		} else {
			sign, _ = model.NewUserLoginTokenModel(l.ctx, l.svcCtx.Db).GetSignByUserIdAndPlatform(claims.ID, claims.Source, claims.Business)
			if sign == "" || sign != claims.Sign {
				commonResp.Code = config.TokenvalidateError
				commonResp.Message = "token has expired"
				return &login_rpc.ParseTokenResponse{CommonResp: &commonResp}, fmt.Errorf("token has expired")
			}
		}
	} else {
		if sign != claims.Sign {
			commonResp.Code = config.TokenvalidateError
			commonResp.Message = "token has expired"
			return &login_rpc.ParseTokenResponse{CommonResp: &commonResp}, fmt.Errorf("token has expired")
		}
	}

	return &login_rpc.ParseTokenResponse{UserId: claims.ID, Source: claims.Source, Business: claims.Business, IsAdmin: claims.IsAdmin, UserName: claims.UserName, CommonResp: &commonResp}, nil
}
